package com.pocket.insight.base.config.mybatis.typeHandler;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import java.io.*;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class SerializableTypeHandler extends BaseTypeHandler<Object> {
    public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
        ps.setObject(i, javaSerialize(parameter));
    }


    public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
        byte[] val = rs.getBytes(columnName);
        if (val == null) {
            return null;
        }
        return javaDeserialize(val);
    }


    public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        byte[] val = rs.getBytes(columnIndex);
        if (val == null) {
            return null;
        }
        return javaDeserialize(val);
    }


    public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        byte[] val = cs.getBytes(columnIndex);
        if (val == null) {
            return null;
        }
        return javaDeserialize(val);
    }


    public static Object javaDeserialize(byte[] data) {
        if (data != null) {
            try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data);
                 ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);){
              Object object = objectInputStream.readObject();
              objectInputStream.close();
              byteArrayInputStream.close();
              return object;
            } catch (IOException | ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static byte[] javaSerialize(Object object) {
        if (object != null) {
            try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                 ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);){
              objectOutputStream.writeObject(object);
              byte[] arrayOfByte = byteArrayOutputStream.toByteArray();
              objectOutputStream.close();
              byteArrayOutputStream.close();
              return arrayOfByte;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}
